--- title: "03-C语言笔试 最终版" created: 2026-01-11 tags: - 博客 --- # C语言笔试 最终版 ## 题型分布 一、选择题(共20小题,每小题1分,共20分) 二、填空题(共10空,每空1分,共10分) 三、判断题(共10小题,每小题1分,共10分) 四、程序阅读题(共5小题,每小题4分,共20分) 五、算法设计题(共2小题,每小题8分,共16分) 六、程序设计题(共2小题,每小题12分,共24分) ## **一、选择题(共20小题,每小题1分,共20分)** ### 1、考察基础知识 **题目**:下列叙述中正确的是\_\_\_\_\_\_。 A、C程序的基本组成单位是语句 **B、C语句必须以分号结束** C、C程序中的每一行只能写一条语句 D、C程序必须在一行内写完 - **解析:** - C语言中,程序基本组成单位是 **函数** **,**基本执行单位是 **语句** ,以分号结尾。 **题目**:可以将用高级语言编写的源程序转换为目标程序的程序是\_\_\_\_\_\_。 A. 汇编程序 B. 解释程序 C. 编辑程序 **D. 编译程序** - **解析:** - c语言是编译型语言,python是解释型语言。 ### 2、考察标识符 **题目**:**下列选项中,不能用作c语言标识符的是\_\_\_\_\_** A、print B、FOR **C、&a** D、\_00 - 解析: - 只能是字母数字下划线,"&"不合法。 ### 3、考察格式化输出与 ASCII 码 **题目**:已知字符 `a` 的 ASCII 码为 97,执行语句 `printf("%c%d", 'b', 'b'+1);`后输出结果是\_\_\_\_\_\_\_\_ **A、b99** B、98c C、9899 D、bc - **解析**: - `'b'` 的 ASCII 码是 98(因为 `'a'` 是 97,`'b'` 紧随其后)。 - 第一个格式符 `%c` 对应参数 `'b'`:输出字符形式 **b**。 - 第二个格式符 `%d` 对应参数 `'b'+1`:即 `98 + 1 = 99`。`%d` 要求输出整数形式,所以输出 **99**。 - 拼接起来就是 `b99`。 **题目:**已知字符 `a` 的 ASCII 码为 97,执行语句 `printf("%d,%c", 'b', 'b'+1);`后输出结果是\_\_\_\_\_\_\_\_ A、98,b B、语句不合法 C、98,99 **D、98,c** ### 4、考察字符串常量 **题目:**表达式sizeof("key")的值是\_\_\_\_\_\_\_\_ A、1 B、2 C、3 **D、4** - **解析**: - 0 1 2 3 - k e y \0 ### 5、考察数学库 **题目:**要调用数学函数时,在#include命令行应该包含 \_\_\_\_\_\_\_\_ A、stdio.h B、string.h **C、math.h** D、ctype.h ### 6、考察运算符 **题目:**若变量已正确定义,则语句if(a>b) k=0; else k=1和\_\_\_\_\_\_\_ 等价。 A、k=(a>b)?1:0; B、k=a>b; **C、k=a≤b;** D、a≤b?0:1; - **解析**: - 列出一个逻辑表 - **情况 1**:当 `a > b` 成立(真)时 \(\rightarrow\) `k` 被赋值为 **0**。 - **情况 2**:当 `a > b` 不成立(假)时 \(\rightarrow\) `k` 被赋值为 **1**。 - 逐个分析选项 - **选项 A:**`k=(a>b)?1:0;` - **含义**:这是三目运算符。如果 `a>b` 为真,取冒号前面的值(1);否则取冒号后面的值(0)。 - **结果**:真 \(\rightarrow\) 1,假 \(\rightarrow\) 0。 - **结论**:这与原题目的逻辑刚好**相反**。 - **选项 B:**`k=a>b;` - **含义**:直接将关系表达式的结果赋值给 k。 - **C语言规则**:关系运算(如 `>`)的结果只有两种:真为 1,假为 0。 - **结果**: - 如果 `a > b` 为真,表达式值为 1 \(\rightarrow\) `k = 1`。 - 如果 `a > b` 为假,表达式值为 0 \(\rightarrow\) `k = 0`。 - **结论**:这也与原题目逻辑**相反**(同 A 选项)。 - **选项 C:**`k=a<=b;` - **含义**:判断 `a` 是否小于等于 `b`,并将结果(1或0)赋值给 `k`。 - **逻辑转换**: - 当原题条件 `a > b` 成立(真)时 \(\rightarrow\) 它的反面 `a <= b`就不成立(假,值为 0)。此时 `k = 0`。**(符合原题)** - 当原题条件 `a > b` 不成立(假)时 \(\rightarrow\) 它的反面 `a <= b`就成立(真,值为 1)。此时 `k = 1`。**(符合原题)** - **结论**:完全等价。 - **选项 D:**`a<=b?0:1;` - **含义**:这是一个合法的 C 语言表达式,计算出了结果。 - **致命伤**:**没有赋值动作!** 也就是没有写 `k = ...`。算出结果后,没有把值给变量 `k`,所以这条语句执行完,`k` 的值不会发生改变。 - **结论**:不等价。 **题目:**表达式 x&&1 等价于\_\_\_\_\_\_。 A. x==0 B. x==1 **C. x!=0** D. x!=1 - 解析: - **运算符**:`&&` 是逻辑与运算符。 - **规则**:**“同真才真,一假则假”**。只有当两个操作数都为真(非0)时,结果才为 1;否则为 0。 - **操作数分析**: - 右边的操作数是 `1`:这是**真值**(True)。 - 左边的操作数是 `x`:这是变量。 - 因为右边已经是**真**了,所以整个表达式的结果**完全取决于** `x`: - 如果 `x` 是真(非0),则 `真 && 真` \(\rightarrow\) 结果为 **1 (真)**。 - 如果 `x` 是假(0),则 `假 && 真` \(\rightarrow\) 结果为 **0 (假)**。 - **结论:** 这个表达式的作用就是判断 **“x 是不是真的”**(即 x 是不是非 0)。 ![[image-3160d407.png]] ### 7、考察自增自减 **题目:**已知有声明`int x,a=3,b=2;`,则执行赋值语句 `x=a>b++?a++:b++`后,变量x、a、b的值分别为\_\_\_\_\_ 。 **A、3 4 3** B、3 3 4 C、3 3 3 D、4 3 4 - **解析**: - `x=a>b++?a++:b++` - step1: a>b? → 3>2 → true b++ → b=2+1=3 - step2: x=a++ → x=a=3 a++ → a=3+1=4 - step3: x=3 a=4 b=3 **题目:** ``` int a=5; int b,c; b=++a; c=a++; a, b, c的值最终是多少? ``` ``` ++a a=6 b=a=6 c=a=6 a++ a=7 a=7 b=6 c=6 ``` **题目:** ``` int a=0,b=3,c=2; if(a++&&b++) c--; else if(a+1==6 || b--) c++; a、b、c的值最终是多少? ``` ``` && 且 有0则0 左边为0 直接不看右边 if(a++&&b++) -> if(0&&b++) -> if(0) c--; 不执行 不执行 a用完后++ a=0+1=1 || 且 有1则1 左为1 不看右边 else if(a+1==6 || b--) 1+1==6 × (0 || 3) -> true (1) b用完后-- b=3-1=2 执行里面 c++ c=2+1=3 a=1 b=2 c=3 ``` ![[image-f390c144.png]] ### 8、考察 if 语句的作用范围与逗号表达式 **题目**:定义 `int x=4,y=3,z=5;`,下列四个程序段中有 3 个程序段的执行结果相同,另一个执行结果不同的是\_\_\_\_\_\_\_\_ A、if(x>y) z=x,x=y,y=z; B、if(x>y) { z=x,x=y,y=z;} **C、if(x>y) z=x;x=y;y=z;** D、if(x>y) {z=x;x=y;y=z;} - **解析**: - `x > y` 即 `4 > 3`,条件为真。 - **A**: `if(x>y) z=x,x=y,y=z;` —— 逗号表达式 `z=x,x=y,y=z` 被视为一条语句。因为条件为真,这三个赋值都会执行。 - **B**: `if(x>y) { z=x,x=y,y=z;}` —— 花括号内包含一条逗号表达式语句,效果同 A,全部执行。 - **D**: `if(x>y) {z=x;x=y;y=z;}` —— 花括号内包含三条独立语句,因为有花括号包裹,全部受 `if` 控制,全部执行。 - **C**: `if(x>y) z=x; x=y; y=z;` —— **陷阱!** `if`只能控制紧跟其后的第一条语句(即 `z=x;`)。后面的 `x=y;`和 `y=z;` 与 `if` 无关,无论条件真假都会执行。 - 虽然在本题具体数值下,条件为真,看起来大家都执行了。但从**程序逻辑结构**来看,C 的控制范围与其他三项不同(如果 `x>y`为假,A/B/D 什么都不做,而 C 依然会执行后两句赋值)。 ### 9、考察do-while 循环 **题目**:程序段 `int n=3; do{ printf("%d",n--);}while(!n);` 的执行结果是\_\_\_\_\_\_\_\_ A、3 2 1 B、死循环 C、2 **D、3** - **解析**: 1. **第一次执行循环体**:打印 `n` (3),然后 `n`自减变为 2。 2. **判断条件**:`while(!n)` 即 `while(!2)`。在 C 语言中,2 是真,`!2` 就是假 (0)。 3. **结果**:条件为假,循环终止。 4. 所以屏幕上只输出了一个 **3**。 ### 10、考察无符号数 **题目**:设 `int i,a=1; unsigned j;`,则下列语句执行会出现无限循环的语句是\_\_\_\_\_\_\_\_ **A、for(j=15;j>0;j-=2) a++;** B、for(j=0;j>15;j+=2) a++; C、for(i=0;i>15;i+=2) a++; D、for(i=15;i>0;i-=2) a++; - **解析**: - **A**: `for(j=15; j>0; j-=2)`。注意 `j`是 **unsigned (无符号整数)**。 - 序列变化:15, 13, ..., 3, 1。 - 下一步:`1 - 2`。在数学上是 -1,但在计算机无符号数运算中,它会变成一个巨大的正整数(通常是 `2^32 - 1`)。 - 结果:这个巨大的数依然 `> 0`,循环条件永远成立,导致死循环。 - **B/C**: 初始条件 `0 > 15` 不成立,一次都不执行。 - **D**: `i` 是 `int` (有符号)。 `1 - 2`变成 `-1`。`-1 > 0` 为假,循环正常结束。 ### 11、考察循环语句的特性 **题目**:下列关于循环语句 for、while、do-while 的叙述中正确的是\_\_\_\_\_\_\_\_ **A、三种循环语句都可能出现无穷循环** B、三种循环语句中都可以缺省循环终止条件表达式 C、三种循环语句的循环体都至少被无条件地执行一次 D、三种循环语句的循环体都必须放入一对花括号中 - **解析**: - **A**: 正确。只要条件设置不当(如 `while(1)`),三种循环都可能死循环。 - **B**: 错误。`for(;;)` 可以缺省条件,但 `while()`和 `do-while()` 的括号内必须有表达式(哪怕是常数 1)。 - **C**: 错误。`for` 和 `while` 是“先判断后执行”,可能一次都不执行。只有 `do-while`至少执行一次。 - **D**: 错误。如果循环体只有一条语句,花括号 `{}` 可以省略。 **题目:**在c语言中,whiile和do while循环的主要区别是\_\_\_\_\_\_ **A、do while 的循环体至少无条件执行一次** B、do while 允许从外部转到循环体内 C、while的循环控制条件比do while的更严格 D、do while 的循环体不能是复合语句 ### 12、考察数组声明 **题目:**下列**数组声明**语句正确的是\_\_\_\_\_\_\_\_ A、int n, a[n]; B、int a[]; C、int a[2][3]={{2},{1},{3}}; **D、int a[][3]={{2},{1},{3}};** - **解析**: - A: `n`是变量且还没有被初始化,不能用来定义数组长度。 - B:只有在两种情况下可以省略数组长度: - 声明的同时进行了初始化:`int a[] = {1, 2, 3};`(编译器会自动数个数)。 - 作为函数的形参:`void func(int a[])`。 - C:**越界(初始值过多)**。 - **分析:** 声明 `a[2][3]` 意味着这个数组只有 **2 行**。 - **初始值:** `{{2}, {1}, {3}}` 这里的三个大括号代表试图填充 **3 行** 数据。 - D:“行可省,列不可省”。 - 声明了列数是 `3`(不可省略,必须告诉编译器一行有多宽)。 - 省略了行数 `[]`。 - 编译器去数后面的初始值:`{2}` 是第一行,`{1}` 是第二行, `{3}`是第三行。 - 编译器自动推导出:哦,原来有 **3 行**。 - 最终等价于:`int a[3][3] = {{2,0,0}, {1,0,0}, {3,0,0}};`。 ### 13、考察函数形参声明 **题目**:下列关于**函数形参的声明**中正确的是\_\_\_\_\_\_\_\_ A、int a[][] **B、int a[]** C、int a[]={0} D、int a[2][] - **解析**: - **B**: `int a[]` —— 正确。作为函数参数时,一维数组可以不写长度(本质是退化为指针 `int *a`)。 - **A/D**: `int a[][]` 和 `int a[2][]` —— 错误。多维数组作为参数,**第一维可以省略,但后面的维度必须写明**(例如 `int a[][5]` 是对的)。编译器需要知道列宽来计算地址。 - **C**: `int a[]={0}` —— 错误。函数形参只是声明,**不能在参数列表中进行初始化赋值**。 **题目**:下列函数定义的头部中正确的是\_\_\_\_\_\_。 A. int fun(int a[], b) B. int fun(int a[], int a) **C. int fun(int a, int b)** D. int fun( int char a[][], int b) ### 14、考察构造数据类型 **题目**:在c语言中,下列属于构造类型的是 A、整型 B、实型 C、指针类型 **D、结构体类型** **题目**:若要使表达式 x++ 无语法错误,则变量 x 不能声明为\_\_\_\_\_\_。 A. float x; B. long x; C. int \*x; **D. struct{int y;}x;** ### 15、考察文件写入 **题目**:下列函数中,可以把整型数据以二进制形式写入文件中的函数是\_\_\_\_\_\_\_\_ A、fputc() **B、fwrite()** C、fread() D、fgetc() - **解析**: - **B**: `fwrite()` —— 专门用于二进制块读写的函数。 - **A**: `fputc()` —— 写入单个字符(文本模式)。 - **C/D**: `fread()` / `fgetc()` —— 都是读取函数,不是写入。 ![[image-8c905c3f.png]] ### 16、考察文件关闭 **题目**:当文件被正常关闭时,fclose()函数的返回值是\_\_\_\_\_\_\_\_ A、-1 B、true **C、0** D、1 - **解析**: - `fclose` 关闭成功返回 **0**。 - 关闭失败返回 **EOF**(通常定义为 -1)。 ### 17、考察宏定义 **题目**:在宏定义语句 `#define PI 3.1415926` 中,宏名 PI 的是\_\_\_\_\_\_\_\_ A、一个字符串 B、一个单精度数 **C、一个常量** D、一个双精度数 - **解析**: - 在 C 语言术语中,用 `#define` 定义的标识符被称为**符号常量**(Symbolic Constant)。 - 它不是字符串(没有双引号),也不是变量。虽然它代表一个双精度数,但“符号常量”是更准确的定义分类。 ![[image-ac0a0a00.png]] ![[image-34cf7327.png]] ### 18、考察宏替换 **题目**:设有定义和声明如下: ``` #define d 2 int a = 3; float b = 3.14; char c = 'd'; ``` 以下表达式中有语法错误的是\_\_\_\_\_\_\_ A、x++ B、y++ C、c++ **D、d++** - **解析**: - 宏定义是**纯文本替换**。预处理阶段会将代码中所有的 `d` 替换为 `2`。 - **A**: `x++` -> `5++`(变量自增,正确)。 - **B**: `y++` -> `3.83++`(变量自增,正确)。 - **C**: `c++` -> `c` 是变量,可以自增。 - **D**: `d++` -> 被替换为 `2++` 。 - **错误原因**:自增运算符 `++` 只能用于**变量**(左值),不能用于**常量**或表达式。你不能强迫数字 2 变成 3。 ![[image-30abfe31.png]] > 注:上面的内容是原题,接下来的内容为推测必考点: ### 19、考察数组常识 在C语言中,数组下标是从( )开始的。 **A. 0** B. 1 C. 2 D. 任意整数 若有定义 int arr[5];,则数组arr的最后一个元素是( )。 A. arr[0] **B. arr[4]** C. arr[5] D. arr[6] 以下关于二维数组的描述,正确的是( ) A. 二维数组在内存中是按列存储的 **B. 二维数组可以看作是一维数组的数组** C. 二维数组的行数和列数必须在编译时确定 D. 二维数组的所有元素必须具有相同的值 ![[image-30e20165.png]] 若定义 int a[10], b[3][3]; ,则以下对数组元素赋值的语句中,不会出现越界访问的是( ) A. a[-1]=0 B. a[10]=0 C. b[3][0]=0 **D. b[0][3]=0** 若定义 int k, a, b; unsigned long y = 5; double x = 1.23; ,则下列表达式中正确的是\_\_\_\_\_\_。 A. x%(-3) B. x=y[5] b C. k=(a=1,b=2,&a+&b) **D. a+=a-=(b=3)\*(a=2)** 若定义 int a[3][2]={1,2,3,4,5,6}; ,则数组元素\_\_\_\_\_\_的值为6。 A. a[3][2] **B. a[2][1]** C. a[1][2] D. a[2][3] ![[image-2c94fd09.png]] ### 20、考察函数常识 什么是形参,什么是实参? - **形参 (Formal Parameter):** - **定义时**括号里的变量。 - 它是“占位符”,函数未被调用时不占内存,只有调用时才分配内存。 - *例子:* `void fun(int a)` 里的 `a`。 - **实参 (Actual Parameter):** - **调用时**括号里传递的具体数值或变量。 - 它是“实际的数据”,必须有确定的值。 - *例子:* `fun(2)` 里的 `2`。k - **关系:** 发生函数调用时,**实参的值会单向复制给形参**(值传递)。 以下函数调用语句中有\_\_\_\_\_\_个实参。 func((a1,a2,a3),(a4,a5)); **A.2** B. 5 C. 1 D. 不合法 ### 21、考察格式化输出 执行printf("%x",100);后的输出结果是\_\_\_\_\_\_。 A. 100 B. 0x100 C. 0X64 **D. 64** 下列语句中有语法错误的是\_\_\_\_\_\_。 **A. printf("%d",0e);** B. printf("%f",0e2); C. printf("%d",0x2); D. printf("%s","0x2"); ### 22、考察表达式运算结果 在C程序中,用\_\_\_\_\_\_表示逻辑值“真”。 A. 小于0的数 **B. 非0的数** C. 非1的数 D. 大于0的数 ``` 问题:int k = a > b; k = ? ``` ``` 若a>b -> true -> 1 k=1 若a>b -> false -> 0 k=0 ``` ### 23、考察switch case ![[image-c37af5b2.png]] ![[image-bd62b477.png]] ### 24、考察字符串比较函数strcmp() ``` 如何通过strcmp函数比较两个字符串? ``` ``` strcmp 函数定义在 头文件中,用于 比较两个字符串。 函数原型: int strcmp(const char *str1, const char *str2); 返回值说明: 返回 0:两个字符串 完全相同 返回 < 0:str1 小于 str2(按 ASCII 码顺序比较) 返回 > 0:str1 大于 str2(按 ASCII 码顺序比较) 注意:strcmp 是区分大小写的。例如 "abc" 和 "ABC" 不相等。 ``` ![[image-fae0ef71.png]] ![[image-2e6d0882.png]] ![[image-03e82a37.png]] ## **二、填空题(共10空,每空1分,共10分)** ### 1、考察三目运算符 **题目**:若定义 `int a=5;` 则表达式 `(a>0 ? a : -a)`的值为 **5** **考点**: - **语法**:`表达式1 ? 表达式2 : 表达式3` - **解析**: 1. 先判断 `表达式1` (即 `a>0`) 是否为真。 2. 因为 `a=5`,所以 `5>0` 成立(为真)。 3. 取 `表达式2` (即 `a`) 的值作为整个表达式的结果。 4. 如果是假,则取 `表达式3` (`-a`)。 - *注:这其实就是求绝对值的逻辑。* ### 2、考察循环结构 **题目:**若循环结构的循环体至少要执行一次,则最适合描述该循环结构的语句是 **do while** 语句。 ### 3、考察数组 **题目:**若有数组a,且数组元素a[0]~a[9]的值为9,4,12,8,2,10,7,5,1,3,则: 该数组中,可用的最小下标为 **0** ,最大下标为 **9** ### 4、考察函数 当 **return** 语句被执行时,程序的执行流程无条件地从一个函数跳转到另一个函数。 用于定义外部函数的关键字是 **extern** ,用于定义内部函数 (静态函数)的关键字是 **static** 。 ### 5、考察输入输出 **题目**:scanf()函数的输入项必须是 **地址** ,不能是变量名。 **考点**: - **scanf 原理**:`scanf` 需要修改变量的值,在 C 语言中,要修改一个变量,必须知道它在内存中的位置。 - **解析**: - 错误写法:`scanf("%d", a);` (只传了值,scanf 找不到屋子在哪,没法把东西放进去)。 - 正确写法:`scanf("%d", &a);` (`&` 取地址符,告诉 scanf 变量 `a` 的门牌号)。 - *特例:如果是字符数组(字符串)* `char str[10]`*, 写* `scanf("%s", str)` *是对的,因为数组名本身就是地址。* ### 6、考察字符输入输出 **题目**:getchar()和putchar()函数只能用于 **单个** 字符的输入和输出。 **考点**: - **函数功能差异**: - `printf/scanf`:格式化,可以处理各种类型,可以处理多个。 - `puts/gets`:专门处理字符串(一串字符)。 - `putchar/getchar`:专门处理**单个字符** (char)。 - **解析**:`getchar` 一次只读一个字, `putchar`一次只打一个字。 ### 7、考察逻辑运算与算术运算 **题目**:若定义“int m=23,n=5;”,则表达式 `!m+m%n` 的值是 **3** **考点**: - **运算符优先级**:`!` (逻辑非) > `%`(取余) > `+` (加法)。 - **逻辑值的数值化**:真为 1,假为 0。 - **解析**: 1. **先算** `!m`: `m`是 23 (非 0 即为真)。对“真”取反就是“假”。在 C 语言中,**假的值是 0**。所以 `!m`变成了 `0`。 2. **再算** `m%n`: `23 除以 5`,商 4 余 3。所以 `m%n` 是 `3`。 3. **最后算加法**:`0 + 3 = 3`。 **题目:**若定义“int x=33,y=4;”,则表达式 `!x+x/y` 的值是 **8** **解析:** ``` !33 → 0 0 + x / y 33 / 4 → 8 0 + 8 0 + 8 = 8 ``` ### 8、考察结构体 **题目**:结构体的每个成员的数据类型可以是基本数据类型,也可以是 **构造** 类型。 **考点**: - **数据类型分类**: - 基本类型:int, float, char 等。 - 构造类型:数组、结构体 (struct)、共用体 (union)。 - **解析**:结构体里可以套娃。比如“学生”结构体里,可以有一个成员是“生日”,而“生日”本身又是一个包含年月日的小结构体。 ### 9、考察sizeof **题目**:使用sizeof()函数计算结构体List的长度的表达式是 **sizeof(struct List)** **考点**: - **sizeof 用法**:`sizeof` 是运算符,不是函数(虽然长得像)。 - **语法**:`sizeof(类型名)` 或 `sizeof(变量名)`。 - **解析**: - 题目说“结构体 List”,通常指的是 `struct List { ... };`。 - 在 C 语言中,引用这个类型时必须带上 `struct` 关键字,即 `struct List`。 - 所以计算大小时写 `sizeof(struct List)`。 ![[image-38c166a9.png]] > 注:上面的内容是原题,接下来的内容为推测必考点: ### 10、考察基础知识 程序设计语言的基本功能包括数据表达与 **数据处理** 。 算法应具备如下几个特征:确定性、有穷性、可行性和 **一个或多个输出** 。 C语言中共有 **32** 个关键字。 一个完整的C程序可以有多个函数,其中有且只能有一个 **main()** 函数。C程序总是从 **main ()函数** 开始执行。 字符(char)是 **1**,短整(short)是 **2**。 整型(int)、单浮点(float) 都是 **4**。 双浮点(double) 是 **8**。 任何程序的结构都可以通过3种基本结构进行组合来实现,分别是 **顺序结构**、 **选择结构** 和**循环结构**。 ### 11、考察输入输出 ``` printf函数调用时,格式说明符数量与实际提供的参数数量不一致时会发生什么? 格式说明符少于参数 int a = 10, b = 20; printf("%d", a, b); %d 只有一个说明符,但提供了两个参数 结果: 只使用第一个参数 a b 被忽略 不会报错,也不会打印 b ``` 执行printf("%d;%d",a,b,c,d);后屏幕上将输出 **2** 个整数。 已知有声明和语句int a;scanf("a=%d",&a);,欲使从键盘上为变量a输入的值为2,则正确的输入应是 **a=2** 。 ``` 格式修饰符都有哪些? %d, %3d, %u, %x, %#x, %ld, %f, %lf, %4.2f, %c, %s的含义分别是什么? ``` ``` %d 含义:输出十进制有符号整数(int) %3d 含义:输出宽度至少为 3 的十进制整数,右对齐 若数字不足 3 位,左边补空格 若超过 3 位,直接原样输出 %u 含义:输出无符号十进制整数(unsigned int) 同一块内存,按“无符号”方式解释 %x 含义:以十六进制输出整数(小写字母 a–f) 仅影响显示,不改变变量的值 %#x 含义:以十六进制输出,并自动加前缀 0x 字母仍为小写 %ld 含义:输出 long int 类型的十进制整数 用于 long 型整数 %f 含义:输出浮点数(float / double) 默认 保留 6 位小数 %lf 含义: printf 中:等价于 %f scanf 中:表示读入 double %4.2f 含义: 总宽度至少为 4 小数点后保留 2 位 默认右对齐 %c 含义:输出一个字符 对应 char 类型或字符常量 %s 含义:输出字符串(以 \0 结尾的字符数组) 不输出 \0 printf("%c,%d", 'A', 'A'); %c 'A' 作为字符输出 输出字符:A %d 'A' 实际是字符常量 在 C 语言中,字符本质是整数(ASCII 码) 'A' 的 ASCII 值是 65 ``` 输入输出的格式控制字符中,int型数据采用 **%d** ,float型数据采用 **%f** ,char型数据采用 **%c**。 ``` printf(“%c,%d”, ‘A’,’A’); ``` ``` 实际输出结果: A,65 ``` ### 12、考察字符数组 以下代码段的输出结果是 **China** 。 char ch[20] = {"China\0Beijing"}; printf("%s", ch); ``` sizeof(“hello”)=? ``` ``` 6 末尾有\0 ``` ### 13、考察指针(应该不考 看不懂可跳过) 第 1 题:指针与变量别名 ``` int k=1,j=2; int *p=&k, *q=&j; // p 指向 k,q 指向 j (*p)++; // 1. 取 p 指向的值(k)并自增。k 从 1 变成 2。 k=j; // 2. 把 j 的值(2)赋给 k。此时 k 还是 2。 (*p)++; // 3. 取 p 指向的值(k)并自增。k 从 2 变成 3。 printf("%d, %d",k,j); ``` **结果:** `3, 2` C ``` int k=1,j=2; int *p=&k, *q=&j; // p 指向 k,q 指向 j (*p)++; // 1. 取 p 指向的值(k)并自增。k 从 1 变成 2。 k=j; // 2. 把 j 的值(2)赋给 k。此时 k 还是 2。 (*p)++; // 3. 取 p 指向的值(k)并自增。k 从 2 变成 3。 printf("%d, %d",k,j); ``` **核心考点:** - `*p` 就是 `k` 的替身。动 `*p`就是动 `k`。 - `q` 和 `j` 在这道题里其实是打酱油的, `j`的值全程没变,一直是 2。 第 2 题:循环陷阱与指针移动 **结果:** `0BC` **代码拆解:** **第一部分:分号陷阱** ``` int k; char *s="ABC"; for(k=10; k!=0; k--); // ⚠️ 注意这里有个分号! printf("%d",k); ``` C ``` int k; char *s="ABC"; for(k=10; k!=0; k--); // ⚠️ 注意这里有个分号! printf("%d",k); ``` - 这个 `for` 循环后面直接跟了分号,说明循环体是**空**的。 - 它会一直空转,直到 `k` 减到 `0` 为止。 - 所以 `printf` 输出的是 **0**。 **第二部分:指针的“吃字”现象** ``` while(*s++) putchar(*s); ``` C ``` while(*s++) putchar(*s); ``` 这是一个非常经典的逻辑陷阱: 1. **判断阶段**:先取 `*s` 的值(也就是 'A')来判断循环条件(真)。 2. **自增阶段**:判断完瞬间,`s++` 生效,指针向后移一位,指向了 'B'。 3. **执行阶段**:执行 `putchar(*s)`。注意!此时 `s`已经指向 'B' 了。 - 所以第一次输出的是 **B**('A' 被跳过了)。 4. **下一次循环**: - 判断:取 `*s` ('B') 为真。 - 自增:`s` 移向 'C'。 - 执行:输出 **C**。 5. **再下一次**: - 判断:取 `*s` ('C') 为真。 - 自增:`s` 移向 '\0' (结束符)。 - 执行:输出结束符(看不见)。 6. **最后**: - 判断:取 `*s` ('\0') 为假,循环结束。 所以最终连起来是 `0` `B` `C`。 第 3 题:全局变量、传值与传址 **结果:** `4,3,4,2,7--1,5,4,1,6` 这道题必须分步骤跟踪内存。 **全局变量初始状态:** `x=5`, `y=2`, `z=0` 第一步:`p(&x, y)` 调用 - **传参**: - 形参 `*x` 指向全局 `x` (5)。(传址) - 形参 `y` 是全局 `y` 的副本,值为 2。(传值) - **函数内执行**: 1. `--*x;` -> 全局 `x` 减 1,变为 **4**。 2. `y++;` -> 局部副本 `y` 加 1,变为 **3** (不影响全局 y)。 3. `z=*x+y;` -> 全局 `z` = 全局 `x`(4) + 局部 `y`(3) = **7**。 4. `printf`: 输出 `*x`(4) 和 `y`(3)。 - **函数内输出:**`4, 3,` 第二步:`main` 函数中间的 `printf` - 此时回到主函数,看全局变量: - `x` 刚才被改成了 **4**。 - `y` 刚才没被改(传的是值),还是 **2**。 - `z` 刚才被改成了 **7**。 - **主函数输出:**`4, 2, 7--` 第三步:`p(&y, x)` 调用 - **传参**: - 形参 `*x` 指向全局 `y` (2)。(注意!这次指针指着 y) - 形参 `y` 是全局 `x` 的副本,值为 4。(传值) - **函数内执行**: 1. `--*x;` -> 指针指向的是全局 `y`,所以全局 `y`减 1,变为 **1**。 2. `y++;` -> 局部副本 `y` (也就是那个4) 加 1,变为 **5**。 3. `z=*x+y;` -> 全局 `z` = 全局 `y`(1) + 局部 `y`(5) = **6**。 4. `printf`: 输出 `*x`(1) 和 `y`(5)。 - **函数内输出:**`1, 5,` 第四步:`main` 函数最后的 `printf` - 看全局变量最终状态: - `x` 没变,还是 **4**。 - `y` 被改成 **1** 了。 - `z` 被改成 **6** 了。 - **主函数输出:**`4, 1, 6` ## **三、判断题(共10小题,每小题1分,共10分)** > 注:这部分没明确暗示,把一些没归类好的但90%考的整理进来: long long 占8字节 使用%lld格式化输出 unsigned long long 使用%llu格式化输出 switch语句中,各个case和default的出现次序影响执行结果吗? **不影响** 函数调用之前是否需要先声明? - **原则上需要。** 编译器必须先认识这个函数(知道它的名字、参数类型、返回值类型),才能检查调用是否合法。 - **特例:** 如果函数的**定义**(完整代码)写在调用它的位置**之前**,那么定义本身就充当了声明,不需要额外写声明语句。 是否可以调用 main 函数? - **在 C 语言中:可以。** `main` 函数本质上也是一个函数,可以在程序中递归调用自己(虽然在实际开发中极少这样做,容易死循环)。 - *(注:在 C++ 中是禁止调用 main 函数的,但 C 语言考试通常认为可以)*。 c语言本身提供输入输出语句吗? C 语言的“语言本身”不提供输入输出语句;输入输出是由标准库提供的。 - **C 语言核心语法**(如变量、表达式、控制结构、函数定义等)中**没有内建的 I/O 功能**。 也就是说,像 `printf`、`scanf` 这样的函数不是语言内置语句。 - **I/O 由 C 标准库提供** 标准库 `` 中定义了常用的输入输出函数,例如: - `printf()`:格式化输出到标准输出 - `scanf()`:从标准输入读取格式化数据 - `putchar()`、`getchar()`:字符输入输出 - `fopen()`、`fread()`、 `fwrite()`等:文件操作 - **所以:C 语言的 I/O 是“库函数”,而不是“语言关键字或语句”**。 这与一些语言(如 Python 的 `print` 是关键字或内建函数)不同。 C语言为文件的操作提供了一系列标准函数,它们定义在stdio.h中,因此进行文件操作时需要使用文件包含命令 #include 。文件操作涉及下列一些函数。 (1) 字符读写函数:**fputc() 和 fgetc() 。** (2) 字符串读写函数: fputs() 和 fgets() 。 (3) 格式化读写函数: fscanf() 和 fprintf() 。 (4) 二进制读写函数: fread() 和 fwrite() 。 ## **四、程序阅读题(共5小题,每小题4分,共20分)** ### 1、考察字符型变量(ASCII码 大小写转换) 非真题:(但由书上两道可能是真题的题目合成) ``` #include int main() { char c1, c2; // 步骤 1:初始化 c1 = 65; // 考点 A:直接赋整数值 c2 = 'b'; // 考点 A:赋字符形式 // 步骤 2:运算(大小写转换) c1 = c1 + 32; // 考点 B:大写转小写 c2 = c2 - 32; // 考点 B:小写转大写 // 步骤 3:输出 printf("%c, %d\n", c1, c1); printf("%c, %d\n", c2, c2); return 0; } ``` 初始化的本质(考点 A) - `c1 = 65;` - **内存视角:** 计算机在 `c1` 里存入二进制的 **65**。 - **理解:** 虽然赋值的是整数,但在 ASCII 码表中,65 对应的就是大写字母 **'A'**。 - `c2 = 'b';` - **内存视角:** 计算机查表找到 'b' 的 ASCII 码是 **98**,存入二进制的 98。 运算逻辑(考点 B) - `c1 = c1 + 32;` - 即 `65 + 32 = 97`。 - 在 ASCII 码性质中,**大写字母 + 32 = 对应的小写字母**。 - 此时 `c1` 变成了 **97**(即字符 **'a'**)。 - `c2 = c2 - 32;` - 即 `98 - 32 = 66`。 - 在 ASCII 码性质中,**小写字母 - 32 = 对应的大写字母**。 - 此时 `c2` 变成了 **66**(即字符 **'B'**)。 输出格式 - **第一行** `printf("%c, %d", c1, c1)`**:** - `%c` 输出 `c1` (97) 对应的字符 \(\rightarrow\) **a** - `%d` 输出 `c1` (97) 对应的数值 \(\rightarrow\) **97** - **第二行** `printf("%c, %d", c2, c2)`**:** - `%c` 输出 `c2` (66) 对应的字符 \(\rightarrow\) **B** - `%d` 输出 `c2` (66) 对应的数值 \(\rightarrow\) **66** **答案:** ``` a, 97 B, 66 ``` ### 2、考察 Sizeof 与 运算符优先级 非真题:(但由书上两道可能是真题的题目合成)(可能不考这个 考13456五道) ``` #include int main() { int a, b; // 考点 A:混合运算的类型提升(括号内) // 3(int) + 5.0(double) -> 结果类型为 double a = sizeof(3 + 5.0); // 考点 B:优先级与隐式转换(无括号) // sizeof 3 先算,结果再加 5.0,最后赋值给 int b b = sizeof 3 + 5.0; // 考点 C:基本数据类型与字符串(\0) // sizeof(short) vs sizeof("China") printf("%d, %d, %d, %d\n", sizeof(short), a, b, sizeof("China")); return 0; } ``` 1. 基本类型的长度 `sizeof(short)` - **分析**:这是最基础的死记硬背考点。 - **规则**:`short`(短整型)在标准环境下通常占用 **2** 个字节。 - **结果**:输出 **2**。 2. 类型提升陷阱 `a = sizeof(3 + 5.0)` - **分析**:`sizeof` 计算的是**括号内表达式运算结果的数据类型**长度。 - **过程**: - `3` 是整数 (`int`)。 - `5.0` 默认是双精度浮点数 (`double`)。 - **规则**:C 语言运算时,"小类型"往"大类型"靠。`int` + `double` \(\rightarrow\) `double`。 - `double` 类型占用 8 个字节。 - **结果**:输出 **8**。 3. 优先级陷阱 `b = sizeof 3 + 5.0` - **分析**:这里没有括号,拼的是优先级。 - **过程**: 1. **优先级**:`sizeof` 运算符的优先级 **高于** `+`号。 2. **第一步**:先算 `sizeof 3`。因为 3 是 `int`,所以 `sizeof 3` 等于 **4**。 3. **第二步**:表达式变成了 `4 + 5.0`。结果是 `9.0`(double)。 4. **第三步**:赋值给 `int b`。浮点数 `9.0`被强制截断为整数 `9`。 - **结果**:输出 **9**。 4. 字符串陷阱 `sizeof("China")` - **分析**:肉眼看到的字符数 vs 实际内存占用。 - **过程**: - 可见字符:C-h-i-n-a (5个)。 - **规则**:字符串常量在内存结束处必须有一个隐形的结束标记 `\0`。 - 计算:5 + 1 = 6。 - **结果**:输出 **6**。 **答案:** ``` 2, 8, 9, 6 ``` ### 3、考察嵌套循环与 Continue 大概率是原题 ``` #include int main() { int i, j, n = 0; for(i = 0; i < 2; i++) { n++; for(j = 0; j <= 3; j++) { if(j % 2) continue; n++; } n++; } printf("n = %d\n", n); return 0; } ``` - **考点**:逻辑流程控制,`continue` 跳过谁, `n++`执行了几次。 - **解析**: - 外层 `i=0`: `n`变成1。进入内层。 - 内层 `j=0`: 偶数不continue,`n`变成2。 - 内层 `j=1`: 奇数continue (跳过n++)。 - 内层 `j=2`: 偶数不continue,`n`变成3。 - 内层 `j=3`: 奇数continue。 - 内层结束。`n`变成4 (外层最后还有个n++)。 - 外层 `i=1`: `n`变成5。重复一遍内层逻辑, `n`加3,变成8。 - **答案**: ``` n= 8 ``` ![[image-18662853.png]] ![[image-53131d15.png]] ![[image-201cf0fd.png]] 可以尝试掌握:(但大概率不考 就是考上面那题) ``` #include int main() { int n=5; do { switch(n%2) { case 0: n--; break; case 1: n--; continue; } n--; printf("%2d",n); }while(n>0); return 0; } ``` **初始状态:** `n = 5` 第一轮循环 (n=5) 1. 进入 `do`。 2. `switch(5 % 2)` \(\rightarrow\) 结果是 1 \(\rightarrow\) 命中 `case 1`。 3. **Case 1 执行:** - `n--`:n 变为 **4**。 - `continue`:**【关键点】** 直接跳到 while 判断处! - *(后面的* `n--` *和* `printf` *全部被跳过,没执行)* 4. **While 判断:** `4 > 0` 成立。继续循环。 第二轮循环 (n=4) 1. 进入 `do`。 2. `switch(4 % 2)` \(\rightarrow\) 结果是 0 \(\rightarrow\) 命中 `case 0`。 3. **Case 0 执行:** - `n--`:n 变为 **3**。 - `break`:跳出 switch,继续往下走。 4. **Switch 之后:** - `n--`:n 变为 **2**。 - `printf("%2d", 2)`:**【输出】** `2`。 5. **While 判断:** `2 > 0` 成立。继续循环。 第三轮循环 (n=2) 1. 进入 `do`。 2. `switch(2 % 2)` \(\rightarrow\) 结果是 0 \(\rightarrow\) 命中 `case 0`。 3. **Case 0 执行:** - `n--`:n 变为 **1**。 - `break`:跳出 switch,继续往下走。 4. **Switch 之后:** - `n--`:n 变为 **0**。 - `printf("%2d", 0)`:**【输出】** `0`。 5. **While 判断:** `0 > 0` **不成立**。循环结束。 **答案**: ``` 2 0 ``` 难点: - `break` **在** `switch` **中:** - 作用:仅仅跳出 `switch` 语句块。 - 后果:程序**继续向下执行** `switch` 后面的代码(即 `n--`和 `printf`)。 - `continue` **在** `switch` **中(且在循环里):** - 作用:**直接作用于外部的循环**(do-while)。 - 后果:它不仅跳出 switch,还**跳过**了 switch 后面所有的代码(跳过了外面的 `n--` 和 `printf`),直接飞奔去进行 `while(n>0)` 的条件判断! ### 4、考察函数递归 大概率是原题 ``` #include void fun(int a,int b) { if(a >= b) printf("%d",a); // 【位置 A】 else fun(a+1, b); // 【位置 B】递归调用 printf("%d",a); // 【位置 C】这是公用的代码!无论 if 还是 else,最后都会执行这一句! } int main() { fun(1,2); return 0; } ``` 第一层:`main` 调用 `fun(1, 2)` - **参数**:`a=1`, `b=2`。 - **判断**:`if(1 >= 2)` 不成立。 - **执行 else**:进入 【位置 B】,调用下一层递归 `fun(2, 2)`。 - *(注意:此时第一层函数**暂停**在这里,等待第二层运行结束,它手里还捏着最后的 【位置 C】 没执行)* 第二层:递归调用 `fun(2, 2)` - **参数**:`a=2`, `b=2`。 - **判断**:`if(2 >= 2)` 成立! - **执行 if**:进入 【位置 A】,**打印** `2`。 - **当前屏幕:**`2` - **继续执行**:`if` 语句结束,程序继续向下走。 - **执行末尾**:到达 【位置 C】,**打印** `2`。 - **当前屏幕:**`22` - **结束**:第二层函数运行完毕,返回上一层。 回到第一层:`fun(1, 2)` - **继续**:刚才在 【位置 B】 等待的递归调用结束了。 - **继续向下**:程序走到最后的 【位置 C】。 - **此时的 a**:在这一层,`a` 仍然是 **1**。 - **执行末尾**:**打印** `1`。 - **当前屏幕:**`221` ![[diagram-1767590037591-b91b5d69.png]] **答案:** ``` 221 ``` ![[image-216a36db.png]] 练习: ``` #include void fun(int a) { if(!a) printf("%d",a); else fun(a-1); printf("%d",a); } int main() { fun(2); return 0; } ``` ``` 0012 ``` ![[image-03241012.png]] ![[image-d6571bf8.png]] ### 5、考察共用体Union 大概率是原题 ``` #include int main() { union { char c; int i; } s; s.c = 'A'; // 内存里写入 65 (0x41) s.i = 2; // 内存里写入 2。因为共用地址,'A' 被覆盖成了 2。 printf("%d%d", s.c, s.i); return 0; } ``` - **共用起始地址**: - `char c` 和 `int i` 并不是分开存放的,而是**从同一个内存地址开始存放**。 - 可以把共用体想象成一个屋子,同一时间只能住一个人。 - **覆盖过程(Timeline)**: - `s.c = 'A'`:内存的第 1 个字节被写入了 65('A'的ASCII码)。 - `s.i = 2`:这里是关键! `int` 占用 4 个字节(包含第 1 个字节)。当你写入整数 `2` 时,系统会将这 4 个字节全部重写(通常是 `00000010 00000000...` 二进制)。 - **结果**:原本那个位置的 'A' (65) 瞬间被整数 `2` 的低位数据覆盖掉了。 - **输出读取**: - `s.c`:去读第 1 个字节 \(\rightarrow\) 发现是 **2**。 - `s.i`:去读整个 4 字节 \(\rightarrow\) 发现是 **2**。 - 所以输出 `2` 和 `2`,即 `22`。 **答案:** ``` 22 ``` ![[image-a86f6ce8.png]] ### 6、考察宏定义 大概率是原题 ``` #include #define LAB1 0 #define LAB2 2 #include void main() { int temp; #ifdef LAB1 temp=LAB1; #else temp=LAB2; #endif printf("%d",temp); } ``` - **区分** `#ifdef` **和** `#if` : - `#if LAB1`:这是在判断 **真假**。如果代码写的是这个,因为 `LAB1`是 0(假),确实会跳到 `else`。 - `#ifdef LAB1`:这是在判断 **存在性**(Is Defined?)。它完全不关心 `LAB1` 的值是 0、1 还是 100,它只关心:**“你在前面通过** `#define` **提到过** `LAB1` **这个名字吗?”** - **执行逻辑**: - 第一行 `#define LAB1 0` 已经“注册”了 `LAB1` 这个名字。 - 所以在 `#ifdef LAB1` 时,判定结果为 **“存在”**(真)。 - 编译器会保留 `temp = LAB1;` 这一行代码。 - 即 `temp = 0;`。 - **总结**: - 只要 `#define` 出现过,`#ifdef` 就成立。哪怕你定义的是 `#define LAB1`(后面什么都不写),它也是成立的。 **答案:** ``` 0 ``` ![[image-fde6de95.png]] ## **五、算法设计题(共2小题,每小题8分,共16分)** ### **1、考察二维数组与循环** 大概率是真题: **编程计算n×n的矩阵的两条对角线上所有元素(各元素数值任意)之和** ``` #include #define N 5 // 【改这里】定义矩阵大小,如果是5就是5x5,如果是3就是3*3 int main() { int a[N][N] = { {1, 1, 1, 1, 1}, {1, 1, 1, 1, 1}, {1, 1, 5, 1, 1}, {1, 1, 1, 1, 1}, {1, 1, 1, 1, 1} }; // int a[N][N] = { // {9, 4, 7}, // {5, 6, 1}, // {8, 3, 2} // }; int sum = 0, i, j; printf("%d x %d 数组:\n", N, N); // 输出矩阵部分 for(i = 0; i < N; i++) { for(j = 0; j < N; j++) printf("%3d", a[i][j]); printf("\n"); } // 计算求和部分 for(i = 0; i < N; i++) { for(j = 0; j < N; j++) { // 核心公式 // 1. i == j 是主对角线 // 2. i + j == N - 1 是副对角线 (3x3时是2, 5x5时是4) if(i == j || i + j == N - 1) { sum = sum + a[i][j]; } } } printf("对角线元素之和为:%d\n", sum); return 0; } ``` ### **2、考察字符串与指针** 大概率是真题 编程使用字符指针将26个英文字母以每行10个的形式输出 ``` #include int main() { char *str1, *str2; str1 = "abcdefghijklmnopqrstuvwxyz"; // 遍历字符 for(str2 = str1; str2 < str1 + 26; str2++) { printf("%c ", *str2); // 判断是否换行 // str2-str1 得到的是当前字符的下标(0-25) // +1 是为了变成第几个字符(1-26) if((str2 - str1 + 1) % 10 == 0) printf("\n"); } return 0; } ``` ## **六、程序设计题(共2小题,每小题12分,共24分)** ### **1、考察流程图(循环)** **画出完成如下要求的程序对应的流程图:求两个自然数的最大公约数和最小公倍数** ``` /* 【例 5.17】求两个自然数的最大公约数和最小公倍数 */ #include int main() { int a, b, r, n, m; printf("请输入两个整数:"); scanf("%d%d", &a, &b); m = a; n = b; /* 保存原始数值,因为后面 a 和 b 会变 */ /* 核心算法:辗转相除法 */ do { r = a % b; /* 求余数 */ a = b; /* 把除数 b 变成下一轮的被除数 a */ b = r; /* 把余数 r 变成下一轮的除数 b */ } while (r != 0); /* 当余数不为0时,继续循环;余数为0,结束 */ printf("%d和%d的最大公约数是:%d\n", m, n, a); printf("最小公倍数是:%d\n", m * n / a); return 0; } ``` ![[image-31f8f99d.png]] - **开始框(圆角矩形/椭圆)**:写上 `开始`。 - **输入框(平行四边形)**:写 `输入 a, b`。 - **处理框(矩形)**:写 `m = a, n = b`(保存原值)。 - **处理框(矩形)**:写 `r = a % b`。 - **处理框(矩形)**:写 `a = b`。 - **处理框(矩形)**:写 `b = r`。 - **判断框(菱形)**:写 `r != 0 ?` (或者 `r == 0?`)。 - **如果 是 (True)**:箭头指回到第 4 步(求余数的那一步)。 - **如果 否 (False)**:箭头向下继续。 - **处理框(矩形)**:计算最小公倍数 `lcm = m * n / a` (此时 a 已经是最大公约数了)。 - **输出框(平行四边形)**:写 `输出 a, lcm`。 - **结束框(圆角矩形/椭圆)**:写 `结束`。 ### 2、可能还是考察画图(分支) 没有明确的暗示 自己掌握好相关知识点 怎么画图 #### 题目一:寻找最大的数 ![[image-e83f60a2.png]] #### 题目二:有3个数 a, b, c,要求按大小顺序把它们输出 ![[image-0e8d25ad.png]] #### 题目三:判断一个数 n 能否同时被 3 和 5 整除 ![[image-e2352b0f.png]] ### 3、也可能考察程序 不过还是画图可能性大些 出容易点就是 ``` 问题:编程打印数字金字塔。 0 123 23456 3456789 ``` ``` #include int main() { int height = 4; // 金字塔高度 int i, j; for (i = 0; i < height; i++) { // 打印每行前的空格,使数字居中 for (j = 0; j < height - i - 1; j++) { printf(" "); } // 打印数字,每行从 i 开始,长度为 2*i + 1 for (j = 0; j < 2 * i + 1; j++) { printf("%d", i + j); } // 换行 printf("\n"); } return 0; } ``` ``` 问题:求阶乘。 ``` ``` #include int main() { int n; unsigned long long fact = 1; scanf("%d", &n); if (n < 0) { printf("阶乘只适用于非负整数。\n"); return 1; } for (int i = 1; i <= n; i++) { fact *= i; } printf("%d 的阶乘是 %llu\n", n, fact); return 0; } ```